package org.springblade.core.license.server;

import de.schlichtherle.license.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.license.CustomKeyStoreParam;
import org.springblade.core.license.CustomLicenseManager;

import javax.security.auth.x500.X500Principal;
import java.io.File;
import java.text.MessageFormat;
import java.util.Date;
import java.util.prefs.Preferences;

/**
 * License生成类
 *
 * @author zifangsky
 * @date 2018/4/19
 * @since 1.0.0
 */
public class LicenseCreator {


	private static Logger logger = LogManager.getLogger(LicenseCreator.class);
	private final static X500Principal DEFAULT_HOLDER_AND_ISSUER = new X500Principal("CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN");
	private LicenseCreatorParam param;

	public LicenseCreator(LicenseCreatorParam param) {
		this.param = param;
	}

	/**
	 * 生成License证书
	 *
	 * @return boolean
	 * @author zifangsky
	 * @date 2018/4/20 10:58
	 * @since 1.0.0
	 */
	public boolean generateLicense() {
		try {
			LicenseManager licenseManager = new CustomLicenseManager(initLicenseParam());

			LicenseContent licenseContent = initLicenseContent();

			licenseManager.store(licenseContent, new File(param.getLicensePath()));

			return true;
		} catch (Exception e) {
			logger.error(MessageFormat.format("证书生成失败：{0}", param), e);
			return false;
		}
	}

	/**
	 * 初始化证书生成参数
	 *
	 * @return de.schlichtherle.license.LicenseParam
	 * @author zifangsky
	 * @date 2018/4/20 10:56
	 * @since 1.0.0
	 */
	private LicenseParam initLicenseParam() {
		Preferences preferences = Preferences.userNodeForPackage(LicenseCreator.class);

		//设置对证书内容加密的秘钥
		CipherParam cipherParam = new DefaultCipherParam(param.getStorePass());

		KeyStoreParam privateStoreParam = new CustomKeyStoreParam(LicenseCreator.class
			, param.getPrivateKeysStorePath()
			, param.getPrivateAlias()
			, param.getStorePass()
			, param.getKeyPass());

		LicenseParam licenseParam = new DefaultLicenseParam(param.getSubject()
			, preferences
			, privateStoreParam
			, cipherParam);

		return licenseParam;
	}

	/**
	 * 设置证书生成正文信息
	 *
	 * @return de.schlichtherle.license.LicenseContent
	 * @author zifangsky
	 * @date 2018/4/20 10:57
	 * @since 1.0.0
	 */
	private LicenseContent initLicenseContent() {
		LicenseContent licenseContent = new LicenseContent();
		licenseContent.setHolder(DEFAULT_HOLDER_AND_ISSUER);
		licenseContent.setIssuer(DEFAULT_HOLDER_AND_ISSUER);

		licenseContent.setSubject(param.getSubject());
		licenseContent.setIssued(param.getIssuedTime());
		licenseContent.setNotBefore(param.getIssuedTime());
		licenseContent.setNotAfter(param.getExpiryTime());
		licenseContent.setConsumerType(param.getConsumerType());
		licenseContent.setConsumerAmount(param.getConsumerAmount());
		licenseContent.setInfo(param.getDescription());

		//扩展校验服务器硬件信息
		licenseContent.setExtra(param.getLicenseCheckModel());

		return licenseContent;
	}

	public static void main(String[] args) {


		LicenseCreatorParam param = new LicenseCreatorParam();
		String licensePath = StringUtils.join("./key/license.lic");

		param.setSubject("license");
		param.setPrivateAlias("privateKey");
		param.setKeyPass("private_password1234");
		param.setStorePass("public_password1234");
		param.setLicensePath(licensePath);
		param.setPrivateKeysStorePath("./key/privateKeys.keystore");
		param.setIssuedTime(new Date());
		param.setExpiryTime(DateUtil.plusMonths(new Date(), 24));
		param.setConsumerType("User");
		param.setConsumerAmount(1);
		param.setDescription("license");

		LicenseCreator licenseCreator = new LicenseCreator(param);
		boolean result = licenseCreator.generateLicense();

		logger.info(MessageFormat.format("证书生成结果：{0}", result));
	}

}
